﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Pci9014;

namespace MotionCS.Controller
{
    public class Pci9014Api
    {
        /// <summary>
        /// 日志回调
        /// </summary>
        public static Action<string> LogCallback;
        /// <summary>
        /// 是否初始化
        /// </summary>
        public static bool IsOpen { get; set; }
        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        public static int Initial(ref int card_count, int[] card_id)
        {
            int nRet = CPci9014.p9014_initial(ref card_count, card_id);
            if (nRet == 0)
            {
                LogCallback?.Invoke("控制卡初始化成功.");
            }
            else
            {
                LogCallback?.Invoke("控制卡初始化失败.");
            }
            IsOpen = nRet == 0;
            return 0;
        }
        /// <summary>
        /// 关闭控制卡
        /// </summary>
        public static void close()
        {
            int iRet = CPci9014.p9014_close();
            ResultCheck("p9014_close", iRet);
        }
        /// <summary>
        /// 设置输出脉冲方式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pls_outmode"></param>
        public static void set_pls_outmode(int axis, int pls_outmode)
        {
            int iRet = CPci9014.p9014_set_pls_outmode(axis, pls_outmode);
            ResultCheck("p9014_set_pls_outmode", iRet);
        }
        /// <summary>
        /// 设置外部脉冲编码器输入信号类型
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pls_iptmode">0-Pulse/Dir 1-4x AB</param>
        public static void set_pls_iptmode(int axis, int pls_iptmode)
        {
            int iRet = CPci9014.p9014_set_pls_iptmode(axis, pls_iptmode);
            ResultCheck("p9014_set_pls_iptmode", iRet);
        }
        /// <summary>
        /// 设置T型速度/加速度参数
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="start_vel"></param>
        /// <param name="max_vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        public static void set_t_profile(int axis, double start_vel, double max_vel, double acc, double dec)
        {
            int iRet = CPci9014.p9014_set_t_profile(axis, start_vel, max_vel, acc, dec);
            ResultCheck("p9014_set_t_profile", iRet);
        }
        /// <summary>
        /// 设置S曲线相关参数
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="start_vel"></param>
        /// <param name="max_vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="jerk_percent"></param>
        public static void set_s_profile(int axis, double start_vel, double max_vel, double acc, double dec, double jerk_percent)
        {
            int iRet = CPci9014.p9014_set_s_profile(axis, start_vel, max_vel, acc, dec, jerk_percent);
            ResultCheck("p9014_set_s_profile", iRet);
        }
        /// <summary>
        /// 启动轴定脉冲运动
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="dist"></param>
        /// <param name="dist_mode"></param>
        /// <param name="vel_mode"></param>
        public static void pmove(int axis, int dist, int dist_mode, int vel_mode)
        {
            int iRet = CPci9014.p9014_pmove(axis, dist, dist_mode, vel_mode);
            ResultCheck("p9014_pmove", iRet);
        }
        /// <summary>
        /// 启动轴连续运动
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="plus_dir"></param>
        /// <param name="vel_mode"></param>
        public static void vmove(int axis, int plus_dir, int vel_mode)
        {
            int iRet = CPci9014.p9014_vmove(axis, plus_dir, vel_mode);
            ResultCheck("p9014_vmove", iRet);
        }
        /// <summary>
        /// 轴减速停止或立即停止
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="emg_stop"></param>
        /// <returns></returns>
        public static void stop(int axis, int emg_stop)
        {
            int iRet = CPci9014.p9014_stop(axis, emg_stop);
            ResultCheck("p9014_stop", iRet);
        }
        /// <summary>
        /// 配置回零参数
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="mode"></param>
        /// <param name="org_level"></param>
        /// <param name="ez_level"></param>
        public static void home_config(int axis, int mode, int org_level, int ez_level)
        {
            int iRet = CPci9014.p9014_home_config(axis, mode, org_level, ez_level);
            ResultCheck("p9014_home_config", iRet);
        }
        /// <summary>
        /// 回零运动
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="plus_dir"></param>
        /// <returns></returns>
        public static void home_move(int axis, int plus_dir)
        {
            int iRet = CPci9014.p9014_home_move(axis, plus_dir);
            ResultCheck("p9014_home_move", iRet);
        }
        /// <summary>
        /// 设置位置计数器
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="cntr_no"></param>
        /// <param name="pos"></param>
        public static void set_pos(int axis, int cntr_no, int pos)
        {
            int iRet = CPci9014.p9014_set_pos(axis, cntr_no, pos);
            ResultCheck("p9014_set_pos", iRet);
        }
        /// <summary>
        /// 获取位置计算器
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="cntr_no"></param>
        /// <param name="pPos"></param>
        public static void get_pos(int axis, int cntr_no, ref int pPos)
        {
            int iRet = CPci9014.p9014_get_pos(axis, cntr_no, ref pPos);
            ResultCheck("p9014_get_pos", iRet);
        }
        /// <summary>
        /// 设置Do端口输出状态
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="data"></param>
        public static void set_do(int card_no, uint data)
        {
            int iRet = CPci9014.p9014_set_do(card_no, data);
            ResultCheck("p9014_set_do", iRet);
        }
        /// <summary>
        /// 设置Do端口指定位状态
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="bit_no"></param>
        /// <param name="data"></param>
        public static void set_do_bit(int card_no, uint bit_no, uint data)
        {
            int iRet = CPci9014.p9014_set_do_bit(card_no, bit_no, data);
            ResultCheck("p9014_set_do_bit", iRet);
        }
        /// <summary>
        /// 获取Do端口状态
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="pData"></param>
        public static void get_do(int card_no, ref uint pData)
        {
            int iRet = CPci9014.p9014_get_do(card_no, ref pData);
            ResultCheck("p9014_get_do", iRet);
        }
        /// <summary>
        /// 获取Di端口状态
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="pData"></param>
        public static void get_di(int card_no, ref uint pData)
        {
            int iRet = CPci9014.p9014_get_di(card_no, ref pData);
            ResultCheck("p9014_get_di", iRet);
        }
        /// <summary>
        /// 获取Di端口指定位状态
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="bit_no"></param>
        /// <param name="pData"></param>
        public static void get_di_bit(int card_no, uint bit_no, ref uint pData)
        {
            int iRet = CPci9014.p9014_get_di_bit(card_no, bit_no, ref pData);
            ResultCheck("p9014_get_di_bit", iRet);
        }

        /// <summary>
        /// 获取轴专用IO状态
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pStatus"></param>
        public static void get_io_status(int axis, ref uint pStatus)
        {
            int iRet = CPci9014.p9014_get_io_status(axis, ref pStatus);
            ResultCheck("p9014_get_io_status", iRet);
        }
        /// <summary>
        /// 获取指定轴的状态
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pStatus"></param>
        public static void get_motion_status(int axis, ref uint pStatus)
        {
            int iRet = CPci9014.p9014_get_motion_status(axis, ref pStatus);
            ResultCheck("p9014_get_motion_status", iRet);
        }
        /// <summary>
        /// 获取轴当前速度
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pSpeed"></param>
        public static void get_current_speed(int axis, ref double pSpeed)
        {
            int iRet = CPci9014.p9014_get_current_speed(axis, ref pSpeed);
            ResultCheck("p9014_get_current_speed", iRet);
        }
        /// <summary>
        /// 版本信息查询
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pApi_ver"></param>
        /// <param name="pDriver_ver"></param>
        /// <param name="pLogic_ver"></param>
        public static void get_version(int axis, ref uint pApi_ver, ref uint pDriver_ver, ref uint pLogic_ver)
        {
            int iRet = CPci9014.p9014_get_version(axis, ref pApi_ver, ref pDriver_ver, ref pLogic_ver);
            ResultCheck("p9014_get_version", iRet);
        }
        /// <summary>
        /// 版本信息查询
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="pLogic_revision"></param>
        public static void get_revision(int card_no, ref int pLogic_revision)
        {
            int iRet = CPci9014.p9014_get_revision(card_no, ref pLogic_revision);
            ResultCheck("p9014_get_revision", iRet);
        }

        /// <summary>
        /// 设置限位有效电平
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="active_level"></param>
        public static void set_el_level(int axis, int active_level)
        {
            int iRet = CPci9014.p9014_set_el_level(axis, active_level);
            ResultCheck("p9014_set_el_level", iRet);
        }
        /// <summary>
        /// 设置错误停止模式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="stop_mode"></param>
        public static void set_error_stop_mode(int axis, int stop_mode)
        {
            int iRet = CPci9014.p9014_set_error_stop_mode(axis, stop_mode);
            ResultCheck("p9014_set_error_stop_mode", iRet);
        }

        /// <summary>
        /// 设置报警输入
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="active_level"></param>
        public static void set_alarm(int axis, int enable, int active_level)
        {
            int iRet = CPci9014.p9014_set_alarm(axis, enable, active_level);
            ResultCheck("p9014_set_alarm", iRet);
        }
        /// <summary>
        /// 使能比较器
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="enable"></param>
        /// <param name="active_level"></param>
        /// <param name="ref_source"></param>
        /// <param name="length"></param>
        public static void comp_enable(int card_no, int enable, int active_level, int ref_source, int length)
        {
            int iRet = CPci9014.p9014_comp_enable(card_no, enable, active_level, ref_source, length);
            ResultCheck("p9014_comp_enable", iRet);
        }
        /// <summary>
        /// 查询fifo状态
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="stat"></param>
        public static void comp_get_fifoStatus(int card_no, ref uint stat)
        {
            int iRet = CPci9014.p9014_comp_get_fifoStatus(card_no, ref stat);
            ResultCheck("p9014_comp_get_fifoStatus", iRet);
        }
        /// <summary>
        /// 向位置比较强FIFO中添加一个参考位置
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="PosRef"></param>
        public static void comp_add_ref(int card_no, int PosRef)
        {
            int iRet = CPci9014.p9014_comp_add_ref(card_no, PosRef);
            ResultCheck("p9014_comp_add_ref", iRet);
        }
        /// <summary>
        /// 获取当前位置比较器当前使用的参考位置
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="PosRef"></param>
        public static void comp_get_curRef(int card_no, ref int PosRef)
        {
            int iRet = CPci9014.p9014_comp_get_curRef(card_no, ref PosRef);
            ResultCheck("p9014_comp_get_curRef", iRet);
        }
        /// <summary>
        /// 清除保存参考位置数据的FIFO
        /// </summary>
        /// <param name="card_no"></param>
        public static void comp_clr_fifo(int card_no)
        {
            int iRet = CPci9014.p9014_comp_clr_fifo(card_no);
            ResultCheck("p9014_comp_clr_fifo", iRet);
        }
        /// <summary>
        /// 获取成功比较次数
        /// </summary>
        /// <param name="card_no"></param>
        /// <param name="Count"></param>
        public static void comp_get_matchCount(int card_no, ref uint Count)
        {
            int iRet = CPci9014.p9014_comp_get_matchCount(card_no, ref Count);
            ResultCheck("p9014_comp_get_matchCount", iRet);
        }
        /// <summary>
        /// 清除比较次数寄存器的值
        /// </summary>
        /// <param name="card_no"></param>
        public static void comp_clr_matchCount(int card_no)
        {
            int iRet = CPci9014.p9014_comp_clr_matchCount(card_no);
            ResultCheck("p9014_comp_clr_matchCount", iRet);
        }
        /// <summary>
        /// 结果校验
        /// </summary>
        /// <param name="command"></param>
        /// <param name="iRet"></param>
        private static void ResultCheck(string command, int iRet)
        {
            if (iRet == 0)
                return;

            LogCallback?.Invoke($"{command},ResultCode:{iRet}");
        }
    }
}
